From: Jimi Xenidis Date: Mon, 18 Sep 2006 13:23:51 +0000 (-0400) Subject: [POWERPC][XEN] Track the Hard CPUID as configured by the FW X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15658^2~54 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=be11601759a530d0453232dc3d1c49533d5e37c0;p=xen.git [POWERPC][XEN] Track the Hard CPUID as configured by the FW This patch correctly implements and supports hard_smp_processor_id(). Signed-off-by: Jimi Xenidis Signed-off-by: Hollis Blanchard --- diff --git a/xen/arch/powerpc/boot_of.c b/xen/arch/powerpc/boot_of.c index eca84665fd..f80e1074ff 100644 --- a/xen/arch/powerpc/boot_of.c +++ b/xen/arch/powerpc/boot_of.c @@ -957,21 +957,31 @@ static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi) static int __init boot_of_cpus(void) { - int cpus; - int cpu, bootcpu, logical; + int cpus_node; + int cpu_node, bootcpu_node, logical; int result; + s32 cpuid; u32 cpu_clock[2]; + extern uint cpu_hard_id[NR_CPUS]; - cpus = of_finddevice("/cpus"); - cpu = of_getchild(cpus); - result = of_getprop(cpu, "timebase-frequency", &timebase_freq, + /* Look up which CPU we are running on right now and get all info + * from there */ + result = of_getprop(bof_chosen, "cpu", + &bootcpu_node, sizeof (bootcpu_node)); + if (result == OF_FAILURE) + of_panic("Failed to look up boot cpu\n"); + + cpu_node = bootcpu_node; + + result = of_getprop(cpu_node, "timebase-frequency", &timebase_freq, sizeof(timebase_freq)); if (result == OF_FAILURE) { of_panic("Couldn't get timebase frequency!\n"); } of_printf("OF: timebase-frequency = %d Hz\n", timebase_freq); - result = of_getprop(cpu, "clock-frequency", &cpu_clock, sizeof(cpu_clock)); + result = of_getprop(cpu_node, "clock-frequency", + &cpu_clock, sizeof(cpu_clock)); if (result == OF_FAILURE || (result !=4 && result != 8)) { of_panic("Couldn't get clock frequency!\n"); } @@ -983,69 +993,79 @@ static int __init boot_of_cpus(void) cpu_khz /= 1000; of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz); - /* Look up which CPU we are running on right now. */ - result = of_getprop(bof_chosen, "cpu", &bootcpu, sizeof (bootcpu)); - if (result == OF_FAILURE) - of_panic("Failed to look up boot cpu\n"); - - cpu = of_getpeer(cpu); - - /* We want a continuous logical cpu number space. */ + /* We want a continuous logical cpu number space and we'll make + * the booting CPU logical 0. */ cpu_set(0, cpu_present_map); cpu_set(0, cpu_online_map); cpu_set(0, cpu_possible_map); - /* Spin up all CPUS, even if there are more than NR_CPUS, because - * Open Firmware has them spinning on cache lines which will - * eventually be scrubbed, which could lead to random CPU activation. - */ - for (logical = 1; cpu > 0; logical++) { - unsigned int cpuid, ping, pong; - unsigned long now, then, timeout; - - if (cpu == bootcpu) { - of_printf("skipping boot cpu!\n"); - continue; - } + result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); + cpu_hard_id[0] = cpuid; - result = of_getprop(cpu, "reg", &cpuid, sizeof(cpuid)); - if (result == OF_FAILURE) - of_panic("cpuid lookup failed\n"); + /* Spin up all CPUS, even if there are more than NR_CPUS or we are + * runnign nosmp, because Open Firmware has them spinning on cache + * lines which will eventually be scrubbed, which could lead to + * random CPU activation. + */ - of_printf("spinning up secondary processor #%d: ", logical); + /* Find the base of the multi-CPU package node */ + cpus_node = of_finddevice("/cpus"); + if (cpus_node <= 0) { + of_printf("Single Processor System\n"); + return 1; + } + /* Start with the first child */ + cpu_node = of_getchild(cpus_node); - __spin_ack = ~0x0; - ping = __spin_ack; - pong = __spin_ack; - of_printf("ping = 0x%x: ", ping); + for (logical = 1; cpu_node > 0; logical++) { + unsigned int ping, pong; + unsigned long now, then, timeout; + + if (cpu_node == bootcpu_node) { + /* same CPU as boot CPU shich we have already made 0 so + * reduce the logical count */ + --logical; + } else { + result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); + if (result == OF_FAILURE) + of_panic("cpuid lookup failed\n"); - mb(); - result = of_start_cpu(cpu, (ulong)spin_start, logical); - if (result == OF_FAILURE) - of_panic("start cpu failed\n"); + cpu_hard_id[logical] = cpuid; - /* We will give the secondary processor five seconds to reply. */ - then = mftb(); - timeout = then + (5 * timebase_freq); + of_printf("spinning up secondary processor #%d: ", logical); - do { - now = mftb(); - if (now >= timeout) { - of_printf("BROKEN: "); - break; - } + __spin_ack = ~0x0; + ping = __spin_ack; + pong = __spin_ack; + of_printf("ping = 0x%x: ", ping); mb(); - pong = __spin_ack; - } while (pong == ping); - of_printf("pong = 0x%x\n", pong); + result = of_start_cpu(cpu_node, (ulong)spin_start, logical); + if (result == OF_FAILURE) + of_panic("start cpu failed\n"); + + /* We will give the secondary processor five seconds to reply. */ + then = mftb(); + timeout = then + (5 * timebase_freq); + + do { + now = mftb(); + if (now >= timeout) { + of_printf("BROKEN: "); + break; + } - if (pong != ping) { - cpu_set(logical, cpu_present_map); - cpu_set(logical, cpu_possible_map); - } + mb(); + pong = __spin_ack; + } while (pong == ping); + of_printf("pong = 0x%x\n", pong); - cpu = of_getpeer(cpu); + if (pong != ping) { + cpu_set(logical, cpu_present_map); + cpu_set(logical, cpu_possible_map); + } + } + cpu_node = of_getpeer(cpu_node); } return 1; } diff --git a/xen/arch/powerpc/powerpc64/ppc970.c b/xen/arch/powerpc/powerpc64/ppc970.c index 06fd0b63e6..e59571bd35 100644 --- a/xen/arch/powerpc/powerpc64/ppc970.c +++ b/xen/arch/powerpc/powerpc64/ppc970.c @@ -145,7 +145,7 @@ void cpu_initialize(int cpuid) mthsprg0((ulong)parea); /* now ready for exceptions */ printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n", - mfpir(), raw_smp_processor_id(), smp_processor_id()); + mfpir(), hard_smp_processor_id(), smp_processor_id()); #ifdef DEBUG { diff --git a/xen/arch/powerpc/setup.c b/xen/arch/powerpc/setup.c index 1350a63701..eb75a30bd4 100644 --- a/xen/arch/powerpc/setup.c +++ b/xen/arch/powerpc/setup.c @@ -74,6 +74,7 @@ ulong oftree; ulong oftree_len; ulong oftree_end; +uint cpu_hard_id[NR_CPUS] __initdata; cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; cpumask_t cpu_online_map; /* missing ifdef in schedule.c */ cpumask_t cpu_present_map; @@ -227,6 +228,7 @@ static void init_parea(int cpuid) __func__, STACK_ORDER, cpuid); pa->whoami = cpuid; + pa->hard_id = cpu_hard_id[cpuid]; pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE); /* This store has the effect of invoking secondary_cpu_init. */ diff --git a/xen/include/asm-powerpc/powerpc64/procarea.h b/xen/include/asm-powerpc/powerpc64/procarea.h index 11f91b67e6..def6fe71e5 100644 --- a/xen/include/asm-powerpc/powerpc64/procarea.h +++ b/xen/include/asm-powerpc/powerpc64/procarea.h @@ -29,6 +29,7 @@ struct gdb_state; struct processor_area { unsigned int whoami; + unsigned int hard_id; struct vcpu *cur_vcpu; void *hyp_stack_base; ulong saved_regs[2]; diff --git a/xen/include/asm-powerpc/processor.h b/xen/include/asm-powerpc/processor.h index 3b91f554a6..d7a2965154 100644 --- a/xen/include/asm-powerpc/processor.h +++ b/xen/include/asm-powerpc/processor.h @@ -38,7 +38,7 @@ struct domain; struct vcpu; struct cpu_user_regs; extern int cpu_machinecheck(struct cpu_user_regs *); -extern int cpu_scom_init(void); +extern void cpu_scom_init(void); extern void show_registers(struct cpu_user_regs *); extern void show_execution_state(struct cpu_user_regs *); extern void show_backtrace(ulong sp, ulong lr, ulong pc); diff --git a/xen/include/asm-powerpc/smp.h b/xen/include/asm-powerpc/smp.h index 30a585fbbe..9da0ba0804 100644 --- a/xen/include/asm-powerpc/smp.h +++ b/xen/include/asm-powerpc/smp.h @@ -28,9 +28,9 @@ extern int smp_num_siblings; /* revisit when we support SMP */ -#define get_hard_smp_processor_id(i) (global_cpu_table[i]->whoami) #define raw_smp_processor_id() (parea->whoami) -#define hard_smp_processor_id() raw_smp_processor_id() +#define get_hard_smp_processor_id(i) (global_cpu_table[i]->hard_id) +#define hard_smp_processor_id() (parea->hard_id) extern cpumask_t cpu_sibling_map[]; extern cpumask_t cpu_core_map[]; extern void __devinit smp_generic_take_timebase(void);